<?php
$FILESYSTEM_CRAWLER_NORMAL = array(
      'filterFiles'       => array("allow", array()/*ohne dateierweiterung*/, array()/*nur die erweiterung*/),
      /*'filterFolders'     => array("deny"),*/
      'exceptionFiles'    => array("index.html", "index.htm"),
      'exceptionFolders'  => array(".", "..", ".svn"),
      'readFolders'       => true,
      'readFiles'         => true,
      'readWholeFolder'   => 1,
      'rpProtection'      => false, // Schutz vor relativen Pfaden (..)
      'otpType'           => "simple" /* moeglich: simple, advanced, all */
    );
  
$FILESYSTEM_CRAWLER_FOLDERS = array(
      'filterFiles'       => array("allow", array()/*ohne dateierweiterung*/, array("php")/*nur die erweiterung*/),
      /*'filterFolders'     => array("deny"),*/
      'exceptionFiles'    => array("index.html", "index.htm"),
      'exceptionFolders'  => array(".", "..", ".svn"),
      'readFolders'       => true,
      'readFiles'         => false,
      'readWholeFolder'   => 1,
      'rpProtection'      => false, // Schutz vor relativen Pfaden (..)
      'otpType'           => "simple" /* moeglich: simple, advanced, all */
    );
  
$FILESYSTEM_CRAWLER_FILES = array(
      'filterFiles'       => array("allow", array()/*ohne dateierweiterung*/, array("php")/*nur die erweiterung*/),
      /*'filterFolders'     => array("deny"),*/
      'exceptionFiles'    => array("index.html", "index.htm"),
      'exceptionFolders'  => array(".", "..", ".svn"),
      'readFolders'       => false,
      'readFiles'         => true,
      'readWholeFolder'   => 3,
      'rpProtection'      => false, // Schutz vor relativen Pfaden (..)
      'otpType'           => "simple" /* moeglich: simple, advanced, all */
    );

/**
Filesystem-class
*/

class Filesystem
{
  var $_options = array(
    'crawler'           => array(
      'filterFiles'       => array("allow", array()/*ohne dateierweiterung*/, array("php")/*nur die erweiterung*/),
      'filterFolders'     => array("deny"),
      'exceptionFiles'    => array("index.html", "index.htm"),
      'exceptionFolders'  => array(".", "..", ".svn"),
      'readFolders'       => true,
      'readFiles'         => true,
      'readWholeFolder'   => 3,
      'rpProtection'      => false, // Schutz vor relativen Pfaden (..)
      'otpType'           => "simple" /* moeglich: simple, advanced, all */
    )
  );
  
  var $_crwopts = "std";
  
  var $_tmp = array(
    'optEmulator' => array(),
    'dirHandler'  => array()
  );

  function getExt($file) {
    $dot = strrpos($file, '.') + 1;
    return substr($file, $dot);
  }
  
  function stripExt($file) {
		return preg_replace('#\.[^.]*$#', '', $file);
	}
  
  function _pathFolder($path)
  {
    if(strlen($path == 0) || $path[strlen($path)-1]!="/") {
      $path .= "/";
    }
    return $path;
  }
  
  function path($path, $rp = false)
  {
    if($rp) {
      if(strpos($path, '..') !== false) {
        return false;
      }
    }
    // Backslashes ersetzen
    $path = str_replace("\\", "/", $path);
    return str_replace("//", "/", $path);
  }
  
  function _readFolder($path, $tree = 1)
  {
    $crwopt = $this->_options['crawler'];
    if(is_array($this->_crwopts)) {$opt = $this->_crwopts;foreach($opt as $a=>$b){$crwopt[$a]=$b;}}
    $hd = opendir($path);
    $r = array();
    while($file = readdir($hd)) {
      if(is_dir($path.$file) && $crwopt['readFolders'] && !in_array($file, $crwopt['exceptionFolders']) && !$this->_filterFolder($file, $crwopt['filterFolders'])) {
        $a = array($this->_pathFolder($file));
        if($crwopt['otpType']=="advanced" || $crwopt['otpType']=="all") {
          $a[] = "folder";
          if((is_bool($crwopt['readWholeFolder']) && $crwopt['readWholeFolder']) || (is_numeric($crwopt['readWholeFolder']) && $crwopt['readWholeFolder']>$tree)) {
            $a[] = $this->_readFolder($path.$this->_pathFolder($file), $tree+1);
          }
          if($crwopt['otpType']=="all") {
            $a[] = @fileperms($path.$this->_pathFolder($file));
          }
        }
        $r[] = $a;
      } else if(is_file($path.$file) && $crwopt['readFiles'] && !in_array($file, $crwopt['exceptionFiles']) && !$this->_filterFile($file, $crwopt['filterFiles'])) {
        $a = array($file);
        if($crwopt['otpType']=="advanced" || $crwopt['otpType']=="all") {
          $a[] = "file";
          $a[] = filesize($path.$file);
          if($crwopt['otpType']=="all") {
            $a[] = @fileperms($path.$file);
          }
        }
        $r[] = $a;
      }
    }
    closedir($hd);
    return $r;
  }
  
  function _read($path)
  {
    $path = $this->path($path, $this->_options['crawler']['rpProtection']);
    if(!$path) {
      return false;
    }
    
    if(is_dir($path)) {
      return $this->_readFolder($this->_pathFolder($path));
    } else if(is_file($path)) {
      return $this->_readFile($path);
    }
    return false;
  }

  function read()
  {
    $files = func_get_args();
    if(count($files)==0) {
      return false;
    }
    if(count($files)==1) {
      return $this->_read($files[0]);
    }
    
    $r = array(); // return
    foreach($files as $f) {
      if(is_string($f)) {
        $r[] = $this->_read($f);
      }
    }
    return $r;
  }
  
  function _filterFile($file, $rules)
  {
    if(in_array($this->stripExt($file), $rules[1]) || in_array($this->getExt($file), $rules[2])) {
      if($rules[0] == "allow") {
        return false;
      }
      return true;
    }
    if($rules[0] == "allow") {
      return true;
    }
    return false;
  }
  
  function _filterFolder($file, $rules)
  {
    return false;
  }
  
  function opendir($path, $options = 0)
  {
    $this->_crwopts = $options;
    $handler = md5(count($this->_tmp['dirHandler']));
    $this->_tmp['dirHandler'][$handler] = array('ct'=>0, 'fs'=>$this->read($path));
    return $handler;
  }
  
  function readdir($handler)
  {
    if(!isset($this->_tmp['dirHandler'][$handler])) {return false;}
    
    if($this->_tmp['dirHandler'][$handler]['ct']>=count($this->_tmp['dirHandler'][$handler]['fs'])) {return false;}
    $this->_tmp['dirHandler'][$handler]['ct']++;
    return $this->_tmp['dirHandler'][$handler]['fs'][$this->_tmp['dirHandler'][$handler]['ct']-1][0];
  }
  
  function getFileSize($handler)
  {
    if(!isset($this->_tmp['dirHandler'][$handler])) {return false;}
    if($this->_tmp['dirHandler'][$handler]['ct']>=count($this->_tmp['dirHandler'][$handler]['fs'])) {return false;}
    if($this->_tmp['dirHandler'][$handler]['fs'][$this->_tmp['dirHandler'][$handler]['ct']-1][2]=="folder") {return false;}
    return $this->_tmp['dirHandler'][$handler]['fs'][$this->_tmp['dirHandler'][$handler]['ct']-1][2];
  }
  
  function isDir($handler)
  {
    if(!isset($this->_tmp['dirHandler'][$handler])) {return -1;}
    if($this->_tmp['dirHandler'][$handler]['ct']>=count($this->_tmp['dirHandler'][$handler]['fs'])) {return -1;}
    if($this->_tmp['dirHandler'][$handler]['fs'][$this->_tmp['dirHandler'][$handler]['ct']-1][2]=="folder") {return true;}
    return false;
  }
  
  function isFile($handler)
  {
    if(!isset($this->_tmp['dirHandler'][$handler])) {return -1;}
    if($this->_tmp['dirHandler'][$handler]['ct']>=count($this->_tmp['dirHandler'][$handler]['fs'])) {return -1;}
    if($this->_tmp['dirHandler'][$handler]['fs'][$this->_tmp['dirHandler'][$handler]['ct']-1][2]=="file") {return true;}
    return false;
  }
  
  function closedir($handler)
  {
    if(!isset($this->_tmp['dirHandler'][$handler])) {return false;}
    unset($this->_tmp['dirHandler'][$handler]);
    return true;
  }
}
?>